Hotfix

HotfixTest.cs

    using UnityEngine;
    using XLua;

    [Hotfix]
    public class HotfixTest : MonoBehaviour
    {
        LuaEnv luaenv = new LuaEnv();

        public int tick = 0; //如果是private的,在lua设置xlua.private_accessible(CS.HotfixTest)后即可访问

        // Use this for initialization
        void Start()
        {
        }

        // Update is called once per frame
        void Update()
        {
            if (++tick % 50 == 0)
            {
                Debug.Log(">>>>>>>>Update in C#, tick = " + tick);
            }
        }

        void OnGUI()
        {
            if (GUI.Button(new Rect(10, 10, 300, 80), "Hotfix"))
            {
                luaenv.DoString(@"
                    xlua.hotfix(CS.HotfixTest, 'Update', function(self)
                        self.tick = self.tick + 1
                        if (self.tick % 50) == 0 then
                            print('<<<<<<<<Update in lua, tick = ' .. self.tick)
                        end
                    end)
                ");
            }

            string chHint = @"在运行该示例之前,请细致阅读xLua文档,并执行以下步骤:

    1.宏定义:添加 HOTFIX_ENABLE 到 'Edit > Project Settings > Player > Other Settings > Scripting Define Symbols'。
    (注意:各平台需要分别设置)

    2.生成代码:执行 'XLua > Generate Code' 菜单,等待Unity编译完成。

    3.注入:执行 'XLua > Hotfix Inject In Editor' 菜单。注入成功会打印 'hotfix inject finish!' 或者 'had injected!' 。";
            string enHint = @"Read documents carefully before you run this example, then follow the steps below:

    1. Define: Add 'HOTFIX_ENABLE' to 'Edit > Project Settings > Player > Other Settings > Scripting Define Symbols'.
    (Note: Each platform needs to set this respectively)

    2.Generate Code: Execute menu 'XLua > Generate Code', wait for Unity's compilation.


    3.Inject: Execute menu 'XLua > Hotfix Inject In Editor'.There should be 'hotfix inject finish!' or 'had injected!' print in the Console if the Injection is successful.";
            GUIStyle style = GUI.skin.textArea;
            style.normal.textColor = Color.red;
            style.fontSize = 16;
            GUI.TextArea(new Rect(10, 100, 500, 290), chHint, style);
            GUI.TextArea(new Rect(10, 400, 500, 290), enHint, style);
        }
    }

HotfixTest2.cs

    using UnityEngine;
    using System.Collections.Generic;
    using XLua;

    [CSharpCallLua]
    public delegate int TestOutDelegate(HotfixCalc calc, int a, out double b, ref string c);

    [Hotfix]
    public class HotfixCalc
    {
        public int Add(int a, int b)
        {
            return a - b;
        }

        public Vector3 Add(Vector3 a, Vector3 b)
        {
            return a - b;
        }

        public int TestOut(int a, out double b, ref string c)
        {
            b = a + 2;
            c = "wrong version";
            return a + 3;
        }

        public int TestOut(int a, out double b, ref string c, GameObject go)
        {
            return TestOut(a, out b, ref c);
        }

        public T Test1<T>()
        {
            return default(T);
        }

        public T1 Test2<T1, T2, T3>(T1 a, out T2 b, ref T3 c)
        {
            b = default(T2);
            return a;
        }

        public static int Test3<T>(T a)
        {
            return 0;
        }

        public static void Test4<T>(T a)
        { 
        }

        public void Test5<T>(int a, params T[] arg)
        {

        }
    }

    public class NoHotfixCalc
    {
        public int Add(int a, int b)
        {
            return a + b;
        }
    }

    [Hotfix]
    public class GenericClass<T>
    {
        T a;

        public GenericClass(T a)
        {
            this.a = a;
        }

        public void Func1()
        {
            Debug.Log("a=" + a);
        }

        public T Func2()
        {
            return default(T);
        }
    }

    [Hotfix]
    public class InnerTypeTest
    {
        public void Foo()
        {
            _InnerStruct ret = Bar();
            Debug.Log("{x=" + ret.x + ",y= " + ret.y + "}");
        }

        struct _InnerStruct
        {
            public int x;
            public int y;
        }

        _InnerStruct Bar()
        {
            return new _InnerStruct { x = 1, y = 2 };
        }
    }

    [Hotfix]
    public struct StructTest
    {
        GameObject go;
        public StructTest(GameObject go)
        {
            this.go = go;
        }

        public GameObject GetGo(int a, object b)
        {
            return go;
        }
    }

    [Hotfix(HotfixFlag.Stateful)]
    public struct GenericStruct<T>
    {
        T a;

        public GenericStruct(T a)
        {
            this.a = a;
        }

        public T GetA(int p)
        {
            return a;
        }
    }

    public class HotfixTest2 : MonoBehaviour {

        // Use this for initialization
        void Start () {
            LuaEnv luaenv = new LuaEnv();
            HotfixCalc calc = new HotfixCalc();
            NoHotfixCalc ordinaryCalc = new NoHotfixCalc();

            int CALL_TIME = 100 * 1000 * 1000 ;
            var start = System.DateTime.Now;
            for (int i = 0; i < CALL_TIME; i++)
            {
                calc.Add(2, 1);
            }
            var d1 = (System.DateTime.Now - start).TotalMilliseconds;
            Debug.Log("Hotfix using:" + d1);

            start = System.DateTime.Now;
            for (int i = 0; i < CALL_TIME; i++)
            {
                ordinaryCalc.Add(2, 1);
            }
            var d2 = (System.DateTime.Now - start).TotalMilliseconds;
            Debug.Log("No Hotfix using:" + d2);

            Debug.Log("drop:" + ((d1 - d2) / d1));

            Debug.Log("Before Fix: 2 + 1 = " + calc.Add(2, 1));
            Debug.Log("Before Fix: Vector3(2, 3, 4) + Vector3(1, 2, 3) = " + calc.Add(new Vector3(2, 3, 4), new Vector3(1, 2, 3)));
            luaenv.DoString(@"
                xlua.hotfix(CS.HotfixCalc, 'Add', function(self, a, b)
                    return a + b
                end)
            ");
            Debug.Log("After Fix: 2 + 1 = " + calc.Add(2, 1));
            Debug.Log("After Fix: Vector3(2, 3, 4) + Vector3(1, 2, 3) = " + calc.Add(new Vector3(2, 3, 4), new Vector3(1, 2, 3)));

            double num;
            string str = "hehe";
            int ret = calc.TestOut(100, out num, ref str);
            Debug.Log("ret = " + ret + ", num = " + num + ", str = " + str);

            luaenv.DoString(@"
                xlua.hotfix(CS.HotfixCalc, 'TestOut', function(self, a, c, go)
                        print('TestOut', self, a, c, go)
                        if go then error('test error') end
                        return a + 10, a + 20, 'right version'
                    end)
            ");
            str = "hehe";
            ret = calc.TestOut(100, out num, ref str);
            Debug.Log("ret = " + ret + ", num = " + num + ", str = " + str);

            luaenv.DoString(@"
                xlua.hotfix(CS.HotfixCalc, {
                     Test1 = function(self)
                        print('Test1', self)
                        return 1
                     end;
                     Test2 = function(self, a, b)
                         print('Test1', self, a, b)
                         return a + 10, 1024, b
                     end;
                     Test3 = function(a)
                        print(a)
                        return 10
                     end;
                     Test4 = function(a)
                        print(a)
                     end;
                     Test5 = function(self, a, ...)
                        print('Test4', self, a, ...)
                     end
                })
            ");

            int r1 = calc.Test1<int>();
            double r2 = calc.Test1<double>();

            Debug.Log("r1:" + r1 + ",r2:" + r2);

            string ss = "heihei";
            int r3 = calc.Test2(r1, out r2, ref ss);
            Debug.Log("r1:" + r1 + ",r2:" + r2 + ",r3:" + r3 + ",ss:" + ss);

            r3 = HotfixCalc.Test3("test3");
            r3 = HotfixCalc.Test3(2);
            r3 = HotfixCalc.Test3(this);
            Debug.Log("r3:" + r3);
            HotfixCalc.Test4(this);
            HotfixCalc.Test4(2);
            calc.Test5(10, "a", "b", "c");
            calc.Test5(10, 1, 3, 5);

            Debug.Log("----------------------before------------------------");
            TestStateful();
            System.GC.Collect();
            System.GC.WaitForPendingFinalizers();
            luaenv.DoString(@"
                xlua.hotfix(CS.StatefullTest, {
                    ['.ctor'] = function(csobj)
                        return {evt = {}, start = 0}
                    end;
                    set_AProp = function(self, v)
                        print('set_AProp', v)
                        self.AProp = v
                    end;
                    get_AProp = function(self)
                        return self.AProp
                    end;
                    get_Item = function(self, k)
                        print('get_Item', k)
                        return 1024
                    end;
                    set_Item = function(self, k, v)
                        print('set_Item', k, v)
                    end;
                    add_AEvent = function(self, cb)
                        print('add_AEvent', cb)
                        table.insert(self.evt, cb)
                    end;
                    remove_AEvent = function(self, cb)
                       print('remove_AEvent', cb)
                       for i, v in ipairs(self.evt) do
                           if v == cb then
                               table.remove(self.evt, i)
                               break
                           end
                       end
                    end;
                    Start = function(self)
                        print('Start')
                        for _, cb in ipairs(self.evt) do
                            cb(self.start, 2)
                        end
                        self.start = self.start + 1
                    end;
                    StaticFunc = function(a, b, c)
                       print(a, b, c)
                    end;
                    GenericTest = function(self, a)
                       print(self, a)
                    end;
                    Finalize = function(self)
                       print('Finalize', self)
                    end
               })
            ");
            Debug.Log("----------------------after------------------------");
            TestStateful();
            luaenv.FullGc();
            System.GC.Collect();
            System.GC.WaitForPendingFinalizers();

            var genericObj = new GenericClass<double>(1.1);
            genericObj.Func1();
            Debug.Log(genericObj.Func2());
            luaenv.DoString(@"
                xlua.hotfix(CS['GenericClass`1[System.Double]'], {
                    ['.ctor'] = function(obj, a)
                        print('GenericClass<double>', obj, a)
                    end;
                    Func1 = function(obj)
                        print('GenericClass<double>.Func1', obj)
                    end;
                    Func2 = function(obj)
                        print('GenericClass<double>.Func2', obj)
                        return 1314
                    end
                })
            ");
            genericObj = new GenericClass<double>(1.1);
            genericObj.Func1();
            Debug.Log(genericObj.Func2());

            InnerTypeTest itt = new InnerTypeTest();
            itt.Foo();
            luaenv.DoString(@"
                xlua.hotfix(CS.InnerTypeTest, 'Bar', function(obj)
                        print('lua Bar', obj)
                        return {x = 10, y = 20}
                    end)
            ");
            itt.Foo();

            StructTest st = new StructTest(gameObject);
            Debug.Log("go=" + st.GetGo(123, "john"));
            luaenv.DoString(@"
                xlua.hotfix(CS.StructTest, 'GetGo', function(self, a, b)
                        print('GetGo', self, a, b)
                        return nil
                    end)
            ");
            Debug.Log("go=" + st.GetGo(123, "john"));

            GenericStruct<int> gs = new GenericStruct<int>(1);
            Debug.Log("gs.GetA()=" + gs.GetA(123));
            luaenv.DoString(@"
                xlua.hotfix(CS['GenericStruct`1[System.Int32]'], 'GetA', function(self, a)
                        print('GetA',self, a)
                        return 789
                    end)
            ");
            Debug.Log("gs.GetA()=" + gs.GetA(123));

            try
            {
                calc.TestOut(100, out num, ref str, gameObject);
            }
            catch(LuaException e)
            {
                Debug.Log("throw in lua an catch in c# ok, e.Message:" + e.Message);
            }
        }

        void TestStateful()
        {
            StatefullTest sft = new StatefullTest();
            sft.AProp = 10;
            Debug.Log("sft.AProp:" + sft.AProp);
            sft["1"] = 1;
            Debug.Log("sft['1']:" + sft["1"]);
            System.Action<int, double> cb = (a, b) =>
            {
                Debug.Log("a:" + a + ",b:" + b);
            };
            sft.AEvent += cb;
            sft.Start();
            sft.Start();
            sft.AEvent -= cb;
            sft.Start();
            StatefullTest.StaticFunc(1, 2);
            StatefullTest.StaticFunc("e", 3, 4);
            sft.GenericTest(1);
            sft.GenericTest("hehe");
        }

        // Update is called once per frame
        void Update () {

        }
    }

StatefullTest.cs

    using UnityEngine;
    using System.Collections;

    [XLua.Hotfix(XLua.HotfixFlag.Stateful)]
    public class StatefullTest {
        public StatefullTest()
        {

        }

        public StatefullTest(int a, int b)
        {
            if (a > 0)
            {
                return;
            }

            Debug.Log("a=" + a);
            if (b > 0)
            {
                return;
            }
            else
            {
                if (a + b > 0)
                {
                    return;
                }
            }
            Debug.Log("b=" + b);
        }

        public int AProp
        {
            get;
            set;
        }

        public event System.Action<int, double> AEvent;

        public int this[string field]
        {
            get
            {
                return 1;
            }
            set
            {
            }
        }

        public void Start () {

        }

        void Update () {

        }

        public void GenericTest<T>(T a)
        {

        }

        static public void StaticFunc(int a, int b)
        {
        }
        static public void StaticFunc(string a, int b, int c)
        {
        }

        ~StatefullTest()
        {
            Debug.Log("~StatefullTest");
        }
    }

🔚

results matching ""

    No results matching ""